import FUTClient
import ConfigParser
import logging
import time
import base64

def autoContracts(hours=6, consoleLogging=True):
    """Auto buy contracts and sell/relist."""
    oneCycle = False
    if consoleLogging:
        logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
    else:
        logging.basicConfig(level=logging.INFO, filename="futclient.log", format="%(asctime)s - %(levelname)s - %(message)s")
    try:
        hours = int(hours)
    except ValueError:
        hours = 1
    if hours == 0:
        hours = 1
        oneCycle = True
    config = ConfigParser.ConfigParser()
    config.read("accounts.ini")  # Config file holding login information
    nrAccounts = len(config.sections())
    startTime = int(time.time())
    timeToRun = int(hours*3600)  # time to run script in seconds
    timeBetweenCycles = int(3600/nrAccounts/2)  # time between checking if we need to relist/buy contracts.
    logging.debug("Debugging mode enabled")
    while (startTime+timeToRun)-int(time.time()) > timeBetweenCycles:
        for section in config.sections():
            email = config.get(section, 'email')
            password = readPassword(config.get(section, 'password'))
            the_hash = config.get(section, 'securityhash')
            client = FUTClient.FifaClient(email, password, the_hash)
            logging.info("Account: %s Coins: %s" % (email, client.getCoins()))
            if client.status:
                tradeIDs = list()
                client.relistCards()
                if len(client.getUnAssignedIDs()) > 0:
                    logging.info("There are %i unassigned  items in the bought pile. Processing these." % len(client.getUnAssignedIDs()))
                    while client.getTradePileLength() < client.maxTradePile and len(client.getUnAssignedIDs()) > 0:
                        for x in client.getUnAssignedIDs():
                            client.moveCard(x)
                            time.sleep(1)
                        logging.info("Number of unassigned items left %s" % len(client.getUnAssignedIDs()))
                        client.relistCards()

                logging.info("Starting search for contracts. This might take a while")
                while len(client.getUnAssignedIDs()) == 0 and client.getTradePileLength() < client.maxTradePile and client.getCoins() > 200:
                    logging.debug("Searching for contracts")
                    contracts = client.searchAuctions(cardType="development", category="contract", level="gold", maxBIN=str(200), count="25")
                    if contracts:
                        for contract in contracts:
                            if contract.tradeID not in tradeIDs:  # To fix a bug related to delay when searching
                                tradeIDs.append(contract.tradeID)
                                if contract.resourceID == 1347178283 or True:
                                    logging.debug("Found contract. Attempting to buy.")
                                    if client.buyItem(contract.tradeID, contract.price):
                                        logging.info("Bought Contract for %s" % contract.price)
                                        time.sleep(1)
                                        if client.moveCard(str(contract.itemID)):
                                            logging.info("Moved contract %s to trade pile" % contract.itemID)
                                            bidPrice = "250"
                                            binPrice = "300"
                                            time.sleep(1)
                                            if client.postTrade(str(contract.itemID), bidPrice, binPrice, str(3600)):
                                                logging.info("Listed contract %s for %s / %s. Tradepile %s / %s" % (contract.itemID, bidPrice, binPrice, client.getTradePileLength(), client.maxTradePile))
                    time.sleep(1)

                if not oneCycle:
                    logging.info("Script total running time: %s seconds. %s seconds left" % (int(time.time())-startTime, (startTime+timeToRun)-int(time.time())))
                    logging.info('Sleeping for %s seconds' % timeBetweenCycles)
                    time.sleep(timeBetweenCycles)

    # Relisting contracts for a while after we are done buying
    if not oneCycle:
        relistContracts(hours=2, consoleLogging=consoleLogging)


def relistContracts(hours=1, consoleLogging=True):
    # Script for relisting contracts
    if consoleLogging:
        logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
    else:
        logging.basicConfig(level=logging.WARNING, filename="futclient.log", format="%(asctime)s - %(levelname)s - %(message)s")

    try:
        hours = int(hours)
    except ValueError:
        hours = 1
    config = ConfigParser.ConfigParser()
    config.read("accounts.ini")  # Config file holding login information
    for i in range(0, hours):
        for section in config.sections():
            email = config.get(section, 'email')
            password = readPassword(config.get(section, 'password'))
            the_hash = config.get(section, 'securityhash')
            logging.info("Account %s" % email)
            client = FUTClient.FifaClient(email, password, the_hash)
            if client.status:
                client.relistCards()
        if i+1 < hours:
            time.sleep(3600)


def accountInformation():
    logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
    config = ConfigParser.ConfigParser()
    config.read("accounts.ini")  # Config file holding login information
    total = 0
    for section in config.sections():
        email = config.get(section, 'email')
        password = readPassword(config.get(section, 'password'))
        the_hash = config.get(section, 'securityhash')
        logging.info("Account %s" % email)
        client = FUTClient.FifaClient(email, password, the_hash)
        logging.info("Coins: %s" % client.getCoins())
        total += client.getCoins()
    config2 = ConfigParser.ConfigParser()
    config2.read("main.ini")  # Config file holding login information
    for section in config2.sections():
        email = config2.get(section, 'email')
        password = readPassword(config2.get(section, 'password'))
        the_hash = config2.get(section, 'securityhash')
        logging.info("Account %s" % email)
        client = FUTClient.FifaClient(email, password, the_hash)
        logging.info("Coins: %s" % client.getCoins())
        total += client.getCoins()
    logging.info("Total amount of coins: %s" % total)


def transferMoney(consoleLogging=True):
    """
    Function transfering all money above 10 000 to the main account.
    Need to create main.ini manually at the moment
    """
    if consoleLogging:
        logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
    else:
        logging.basicConfig(level=logging.WARNING, filename="futclient.log", format="%(asctime)s - %(levelname)s - %(message)s")

    mainConfig = ConfigParser.ConfigParser()
    mainConfig.read("main.ini")  # Config file holding main account information
    for section in mainConfig.sections():
        mainEmail = mainConfig.get(section, 'email')
        mainPassword = readPassword(mainConfig.get(section, 'password'))
        mainHash = mainConfig.get(section, 'securityhash')
    config = ConfigParser.ConfigParser()
    config.read("accounts.ini")  # Config file holding login information
    for section in config.sections():
        email = config.get(section, 'email')
        password = readPassword(config.get(section, 'password'))
        the_hash = config.get(section, 'securityhash')
        client = FUTClient.FifaClient(email, password, the_hash)
        buyPrice = int(round(client.getCoins()-10000, -3))
        if buyPrice > 5000:
            client = FUTClient.FifaClient(mainEmail, mainPassword, mainHash)
            cards = client.searchAuctions(level="bronze", formation="f433", league=61, position="defense", maxBIN="200", cardType="player", count=16)
            if client.buyItem(cards[0].tradeID, cards[0].price):
                logging.info("Bought player card for %s" % cards[0].price)
                time.sleep(1)
                if client.moveCard(str(cards[0].itemID)):
                    if client.postTrade(str(cards[0].itemID), '200', buyPrice, str(3600)):
                        logging.info("Listed %s for %s" % (cards[0].itemID, buyPrice))
                        itemID = cards[0].itemID
                time.sleep(5)  # Longer sleep to ensure that trade is posted before moving on
                client = FUTClient.FifaClient(email, password, the_hash)
                cards = client.searchAuctions(level="bronze", formation="f433", league=61, position="defense", minBIN=buyPrice-1000, maxBIN=buyPrice, cardType="player", count=16)
                for i in cards:
                    if i.itemID == itemID:
                        if client.buyItem(i.tradeID, i.price):
                            logging.info("Bough player card for %s" % i.price)
                            time.sleep(5)
                            client.quickSell(itemID)
                            logging.info("Quick sold player")
    logging.info("Money transfered")
    accountInformation()


def readPassword(encodedPassword):
    return base64.b64decode(encodedPassword)


def encodePassword(password):
    return base64.b64encode(password)


class Users(object):
    """Function add, edit or delete users
    and add this information to a config file.
    NOTE: THE CONFIG FILE IS !!!NOT!!! ENCRYPTED
    """
    def __init__(self):
        print "[1] Add User"
        print "[2] Add Main Account"
        print "[0] Exit"
        menu = raw_input("Select option: ")
        if menu == "1":
            self.addNewUser()
        if menu == "2":
            self.addNewMainUser()
        else:
            pass

    def addNewUser(self):
        import EAHash
        config = ConfigParser.ConfigParser()
        email = raw_input("Enter email address: ")
        password = raw_input("Enter your password: ")
        secretQuestion = raw_input("Enter the answer to your secret question: ")
        hashor = EAHash.EAHashingAlgorithm()

        print "Your input: "
        print "Email: %s \nPassword: %s \nAnswer to secret question: %s" % (email, password, secretQuestion)

        if raw_input("Is this correct? [y/n]: ").lower() == "y":
            securityHash = hashor.EAHash(secretQuestion)
            cfgfile = open('accounts.ini', 'a')
            cfgfile.close()
            config.read('accounts.ini')
            existingEmails = []
            #ans = True
            for section in config.sections():
                existingEmails.append(config.get(section, 'email'))
            if email in existingEmails:
                print "ERROR: User exist"
            else:
                cfgfile = open('accounts.ini', 'w')
                config.add_section(email)
                config.set(email, 'email', email)
                config.set(email, 'password', encodePassword(password))
                config.set(email, 'securityHash', securityHash)
                config.write(cfgfile)
                cfgfile.close()
                print "User added"

    def addNewMainUser(self):
        import EAHash
        config = ConfigParser.ConfigParser()
        email = raw_input("Enter email address: ")
        password = raw_input("Enter your password: ")
        secretQuestion = raw_input("Enter the answer to your secret question: ")
        hashor = EAHash.EAHashingAlgorithm()

        print "Your input: "
        print "Email: %s \nPassword: %s \nAnswer to secret question: %s" % (email, password, secretQuestion)

        if raw_input("Is this correct? [y/n] (existing user will be overwritten): ").lower() == "y":
            cfgfile = open('main.ini', 'w')
            config.add_section(email)
            config.set(email, 'email', email)
            config.set(email, 'password', encodePassword(password))
            config.set(email, 'securityHash', hashor.EAHash(secretQuestion))
            config.write(cfgfile)
            cfgfile.close()
            print "New main account added"
        else:
            print "[1] Enter information again \n[Any button] Exit"
            if raw_input("Select: ").lower() == "1":
                self.addNewMainUser()
